package com.blacktea.rabbitmq.springbootrabbitmq.config;

import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * @description: Ttl
 * @author: black tea
 * @date: 2022/6/5 16:19
 */
@Configuration
public class TtlQueueConfig {

    /** 普通交换机 X **/
    public final static String EXCHANGE_X = "X";

    /** 10s ttl队列 QA  **/
    public final static String TTL_QUEUE_A = "QA";

    /** 队列QA绑定交换机X的RoutingKey **/
    public final static String QUEUE_A_BINDING_EXCHANGE_X_ROUTING_KEY = "XA";

    /** 40s ttl队列 QB **/
    public final static String TTL_QUEUE_B = "QB";

    /** 队列QB绑定交换机X的RoutingKey **/
    public final static String QUEUE_B_BINDING_EXCHANGE_X_ROUTING_KEY = "XB";

    /** 自定义 ttl队列 QC **/
    public final static String TTL_QUEUE_C = "QC";

    /** 队列QC绑定交换机X的RoutingKey **/
    public final static String QUEUE_C_BINDING_EXCHANGE_X_ROUTING_KEY = "XC";

    /** 死信交换机 Y **/
    public final static String DEAD_LETTER_EXCHANGE_Y = "Y";

    /** 死信队列 QD **/
    public final static String DEAD_LETTER_QUEUE_D = "QD";

    /** 死信RoutingKey **/
    public final static String DEAD_LETTER_ROUTING_KEY = "YD";

    @Bean("exchangeX")
    public Exchange exchangeX(){
        return new DirectExchange(EXCHANGE_X);
    }

    @Bean("exchangeY")
    public Exchange exchangeY(){
        return new DirectExchange(DEAD_LETTER_EXCHANGE_Y);
    }

    @Bean("ttlQueueA")
    public Queue ttlQueueA(){
        // 10s，进入死信队列
        Long ttl = 10000L;
        return QueueBuilder
                .durable(TTL_QUEUE_A)
                .withArguments(getArguments(ttl))
                .build();
    }

    @Bean("ttlQueueB")
    public Queue ttlQueueB(){
        // 40s，进入死信队列
        Long ttl = 40000L;
        return QueueBuilder
                .durable(TTL_QUEUE_B)
                .withArguments(getArguments(ttl))
                .build();
    }
    @Bean("ttlQueueC")
    public Queue ttlQueueC(){
        return QueueBuilder
                .durable(TTL_QUEUE_C)
                .withArguments(getArguments(null))
                .build();
    }

    @Bean("deadLetterQueueD")
    public Queue deadLetterQueueD(){
        return QueueBuilder
                .durable(DEAD_LETTER_QUEUE_D)
                .build();
    }

    @Bean
    public Binding queueABindingX(@Qualifier("ttlQueueA") Queue ttlQueueA,
                                  @Qualifier("exchangeX") Exchange exchangeX){
        return BindingBuilder
                .bind(ttlQueueA)
                .to(exchangeX)
                .with(QUEUE_A_BINDING_EXCHANGE_X_ROUTING_KEY)
                .noargs();
    }

    @Bean
    public Binding queueBBindingX(@Qualifier("ttlQueueB") Queue ttlQueueB,
                                  @Qualifier("exchangeX") Exchange exchangeX){
        return BindingBuilder
                .bind(ttlQueueB)
                .to(exchangeX)
                .with(QUEUE_B_BINDING_EXCHANGE_X_ROUTING_KEY)
                .noargs();
    }

    @Bean
    public Binding queueCBindingX(@Qualifier("ttlQueueC") Queue ttlQueueC,
                                  @Qualifier("exchangeX") Exchange exchangeX){
        return BindingBuilder
                .bind(ttlQueueC)
                .to(exchangeX)
                .with(QUEUE_C_BINDING_EXCHANGE_X_ROUTING_KEY)
                .noargs();
    }

    @Bean
    public Binding queueDBindingY(@Qualifier("deadLetterQueueD") Queue deadLetterQueueD,
                                  @Qualifier("exchangeY") Exchange exchangeY){
        return BindingBuilder
                .bind(deadLetterQueueD)
                .to(exchangeY)
                .with(DEAD_LETTER_ROUTING_KEY)
                .noargs();
    }


    private Map<String, Object> getArguments(Long ttl){
        Map<String, Object> arguments = new HashMap<>(3);
        // 设置死信交换机
        arguments.put("x-dead-letter-exchange", DEAD_LETTER_EXCHANGE_Y);
        // 设置死信RoutingKey
        arguments.put("x-dead-letter-routing-key", DEAD_LETTER_ROUTING_KEY);
        Optional.ofNullable(ttl).ifPresent(t -> {
            // 设置TTL 单位:ms
            arguments.put("x-message-ttl", t);
        });
        return arguments;
    }

}
